{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b84e1e81",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f946fdd3c15845ba98d134cb513cc957",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Fetching 2 files:   0%|          | 0/2 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from huggingface_hub import snapshot_download\n",
    "\n",
    "f = snapshot_download(\n",
    "    repo_id=\"mesolitica/Animal-Sound-Instructions\",\n",
    "    repo_type='dataset',\n",
    "    allow_patterns=\"data/*.parquet\",\n",
    "    local_dir=\"./Animal-Sound-Instructions\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "acda3802",
   "metadata": {},
   "outputs": [],
   "source": [
    "from glob import glob\n",
    "from tqdm import tqdm\n",
    "from multiprocess import Pool\n",
    "import itertools\n",
    "import zipfile\n",
    "import os\n",
    "\n",
    "def chunks(l, n):\n",
    "    for i in range(0, len(l), n):\n",
    "        yield (l[i: i + n], i // n)\n",
    "\n",
    "\n",
    "def multiprocessing(strings, function, cores=6, returned=True):\n",
    "    df_split = chunks(strings, len(strings) // cores)\n",
    "    pool = Pool(cores)\n",
    "    pooled = pool.map(function, df_split)\n",
    "    pool.close()\n",
    "    pool.join()\n",
    "\n",
    "    if returned:\n",
    "        return list(itertools.chain(*pooled))\n",
    "\n",
    "def loop(files):\n",
    "    files, _ = files\n",
    "    for zip_file_path in tqdm(files):\n",
    "        destination_folder = './'\n",
    "        with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:\n",
    "            zip_ref.extractall(destination_folder)\n",
    "        os.remove(zip_file_path)\n",
    "\n",
    "# files = glob('*.zip')\n",
    "# if len(files):\n",
    "#     multiprocessing(files, loop, cores = min(len(files), 20), returned = False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "356cfc51",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/lib/python3/dist-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.17.3 and <1.25.0 is required for this version of SciPy (detected version 1.26.4\n",
      "  warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion}\"\n"
     ]
    }
   ],
   "source": [
    "from transformers import AutoProcessor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "05a611b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "processor = AutoProcessor.from_pretrained(\"Qwen/Qwen2-Audio-7B-Instruct\")\n",
    "tokenizer = processor.tokenizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3f73f0fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "from glob import glob\n",
    "import pandas as pd\n",
    "\n",
    "rows = []\n",
    "\n",
    "files = glob('Animal-Sound-Instructions/data/*.parquet')\n",
    "for f in files:\n",
    "    df = pd.read_parquet(f).to_dict(orient = 'records')\n",
    "    rows.extend(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "07a8ff8d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "28313"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(rows)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "841c6d3f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'answer': \"Certainly! Here's a description for the 13-second audio clip based on the provided information:\\n\\n---\\n\\n**Scientific Name:** Copiphora colombiae  \\n**Common Name:** Copiphora colombiae  \\n**Class:** Insecta  \\n\\nIn this 13-second audio clip, you can hear the unique and subtle sounds produced by **Copiphora colombiae**, a species of insect native to Colombia. The sounds are likely a combination of stridulation—where the insect rubs its body parts together to create sound—or possibly the movement of wings or other appendages. These sounds are often used for communication, such as attracting mates or warning off predators. The environment in which **Copiphora colombiae** lives might also influence the quality of the sound, with ambient forest noises blending in the background. This species is a fascinating example of the diverse and intricate world of insect communication.\\n\\n---\\n\\nFeel free to adjust any part of this description if you have additional details or specific aspects you'd like to highlight!\",\n",
       " 'question': 'can you describe about the sound that animal makes',\n",
       " 'audio_filename': 'birdclef-2025/CSA18794.mp3',\n",
       " 'metadata': '{\"primary_label\": \"1194042\", \"secondary_labels\": [\"\"], \"type\": [\"\"], \"collection\": \"CSA\", \"rating\": 0.0, \"url\": \"http://colecciones.humboldt.org.co/rec/sonidos/IAvH-CSA-18794/IAvH-CSA-18794.mp3\", \"latitude\": 5.7892, \"longitude\": -73.5504, \"scientific_name\": \"Copiphora colombiae\", \"common_name\": \"Copiphora colombiae\", \"author\": \"Orlando Acevedo-Charry\", \"license\": \"cc-by-nc-sa 4.0\", \"inat_taxon_id\": 1194042, \"class_name\": \"Insecta\", \"audio_filename\": \"birdclef-2025/CSA18794.mp3\", \"len\": 13.493625}'}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rows[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "1f0fe0c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import pandas as pd\n",
    "\n",
    "def loop(rows):\n",
    "    rows, _ = rows\n",
    "    data = []\n",
    "    for r in tqdm(rows):\n",
    "        f = r['audio_filename']\n",
    "        if not os.path.exists(f):\n",
    "            continue\n",
    "            \n",
    "        try:\n",
    "            conversation = [\n",
    "                {\"role\": \"user\", \"content\": [\n",
    "                    {\"type\": \"audio\", \"audio_url\": \"audio.wav\"},\n",
    "                    {\"type\": \"text\", \"text\": r['question']},\n",
    "                ]},\n",
    "                {\"role\": \"assistant\", \"content\": r['answer']},\n",
    "            ]\n",
    "            text = processor.apply_chat_template(conversation, tokenize=False)\n",
    "        except Exception as e:\n",
    "            continue\n",
    "        \n",
    "\n",
    "        data.append({\n",
    "            'text': text,\n",
    "            'audio': f,\n",
    "        })\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b667c078",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4790.86it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4741.00it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4760.80it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4753.75it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4769.70it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4800.83it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4764.33it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4751.72it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4746.58it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4725.37it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4743.50it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4758.70it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4718.08it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4748.89it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4758.46it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4717.67it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4691.59it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4740.16it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4761.85it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4754.45it/s]\n",
      "100%|█████████████████████████████████████████████████████████████████████████████████████| 23/23 [00:00<00:00, 4045.16it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4776.86it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4397.93it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4765.90it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4812.47it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4803.00it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4821.91it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4823.22it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4807.19it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4614.45it/s]\n",
      "100%|███████████████████████████████████████████████████████████████████████████████████| 943/943 [00:00<00:00, 4731.24it/s]\n"
     ]
    }
   ],
   "source": [
    "processed = multiprocessing(rows, loop, cores = 30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b7e7d3c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "28313"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(processed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e30cd7eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('prepare-Animal-Sound-Instructions.json', 'w') as fopen:\n",
    "    json.dump(processed, fopen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a5971c69",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'text': \"<|im_start|>system\\nYou are a helpful assistant.<|im_end|>\\n<|im_start|>user\\nAudio 1: <|audio_bos|><|AUDIO|><|audio_eos|>\\ncan you describe about the sound that animal makes<|im_end|>\\n<|im_start|>assistant\\nCertainly! Here's a description for the 13-second audio clip based on the provided information:\\n\\n---\\n\\n**Scientific Name:** Copiphora colombiae  \\n**Common Name:** Copiphora colombiae  \\n**Class:** Insecta  \\n\\nIn this 13-second audio clip, you can hear the unique and subtle sounds produced by **Copiphora colombiae**, a species of insect native to Colombia. The sounds are likely a combination of stridulation—where the insect rubs its body parts together to create sound—or possibly the movement of wings or other appendages. These sounds are often used for communication, such as attracting mates or warning off predators. The environment in which **Copiphora colombiae** lives might also influence the quality of the sound, with ambient forest noises blending in the background. This species is a fascinating example of the diverse and intricate world of insect communication.\\n\\n---\\n\\nFeel free to adjust any part of this description if you have additional details or specific aspects you'd like to highlight!<|im_end|>\\n\",\n",
       " 'audio': 'birdclef-2025/CSA18794.mp3'}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "processed[0]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
